import redis
import json
from django.conf import settings

class RedisClient:
    """Redis客户端工具类"""
    
    def __init__(self):
        """初始化Redis连接"""
        self.redis_client = None
        self.redis_available = False
        self._fallback_cache = {}  # 内存缓存作为降级方案
        
        try:
            self.redis_client = redis.StrictRedis(
                host=settings.REDIS_HOST,
                port=settings.REDIS_PORT,
                db=settings.REDIS_DB,
                password=settings.REDIS_PASSWORD if settings.REDIS_PASSWORD else None,
                decode_responses=True,  # 自动解码为字符串
                socket_connect_timeout=2,  # 连接超时2秒
                socket_timeout=2  # 读写超时2秒
            )
            # 测试连接
            self.redis_client.ping()
            self.redis_available = True
            print("Redis连接成功")
        except Exception as e:
            print(f"Redis连接失败，使用内存缓存作为降级方案: {str(e)}")
            self.redis_available = False
    
    def set_sms_code(self, phone, code, expire_time=300):
        """
        存储短信验证码
        :param phone: 手机号
        :param code: 验证码
        :param expire_time: 过期时间（秒），默认5分钟
        :return: bool
        """
        try:
            if self.redis_available and self.redis_client:
                key = f"sms_code:{phone}"
                return self.redis_client.setex(key, expire_time, code)
            else:
                # 降级方案：使用内存缓存
                import time
                key = f"sms_code:{phone}"
                expire_at = time.time() + expire_time
                self._fallback_cache[key] = {"code": code, "expire_at": expire_at}
                return True
        except Exception as e:
            print(f"Redis存储短信验证码失败: {str(e)}")
            return False
    
    def get_sms_code(self, phone):
        """
        获取短信验证码
        :param phone: 手机号
        :return: str or None
        """
        try:
            if self.redis_available and self.redis_client:
                key = f"sms_code:{phone}"
                return self.redis_client.get(key)
            else:
                # 降级方案：从内存缓存获取
                import time
                key = f"sms_code:{phone}"
                cache_data = self._fallback_cache.get(key)
                if cache_data and time.time() < cache_data["expire_at"]:
                    return cache_data["code"]
                elif cache_data:
                    # 已过期，删除
                    del self._fallback_cache[key]
                return None
        except Exception as e:
            print(f"Redis获取短信验证码失败: {str(e)}")
            return None
    
    def delete_sms_code(self, phone):
        """
        删除短信验证码（用完即删）
        :param phone: 手机号
        :return: bool
        """
        try:
            if self.redis_available and self.redis_client:
                key = f"sms_code:{phone}"
                return bool(self.redis_client.delete(key))
            else:
                # 降级方案：从内存缓存删除
                key = f"sms_code:{phone}"
                if key in self._fallback_cache:
                    del self._fallback_cache[key]
                    return True
                return False
        except Exception as e:
            print(f"Redis删除短信验证码失败: {str(e)}")
            return False
    
    def check_sms_code_exists(self, phone):
        """
        检查短信验证码是否存在
        :param phone: 手机号
        :return: bool
        """
        try:
            if self.redis_available and self.redis_client:
                key = f"sms_code:{phone}"
                return bool(self.redis_client.exists(key))
            else:
                # 降级方案：检查内存缓存
                import time
                key = f"sms_code:{phone}"
                cache_data = self._fallback_cache.get(key)
                if cache_data and time.time() < cache_data["expire_at"]:
                    return True
                elif cache_data:
                    # 已过期，删除
                    del self._fallback_cache[key]
                return False
        except Exception as e:
            print(f"Redis检查短信验证码失败: {str(e)}")
            return False
    
    def get_sms_code_ttl(self, phone):
        """
        获取短信验证码剩余过期时间
        :param phone: 手机号
        :return: int 剩余秒数，-1表示永不过期，-2表示不存在
        """
        try:
            if self.redis_available and self.redis_client:
                key = f"sms_code:{phone}"
                return self.redis_client.ttl(key)
            else:
                # 降级方案：计算内存缓存剩余时间
                import time
                key = f"sms_code:{phone}"
                cache_data = self._fallback_cache.get(key)
                if cache_data:
                    remaining = int(cache_data["expire_at"] - time.time())
                    if remaining > 0:
                        return remaining
                    else:
                        # 已过期，删除
                        del self._fallback_cache[key]
                        return -2
                return -2
        except Exception as e:
            print(f"Redis获取短信验证码TTL失败: {str(e)}")
            return -2

# 创建全局Redis客户端实例
redis_client = RedisClient() 